home *** CD-ROM | disk | FTP | other *** search
- # -*- coding: utf-8 -*-
- # -*- coding: utf-8 -*-
-
- __author__ = 'Robert Ancell <bob27@users.sourceforge.net>'
- __license__ = 'GNU General Public License Version 2'
- __copyright__ = 'Copyright 2005-2006 Robert Ancell'
-
- __all__ = ['GtkUI']
-
- # TODO: Extend base UI classes?
-
- import os
- import sys
- import time
- from gettext import gettext as _
-
- import gobject
- import gtk
- import gtk.glade
- import gtk.gdk
- import cairo
- import pango
-
- from glchess.defaults import *
- import LaunchpadIntegration
-
- # Stop PyGTK from catching exceptions
- os.environ['PYGTK_FATAL_EXCEPTIONS'] = '1'
-
- import glchess.config
- import glchess.ui
- import glchess.chess.board
- import dialogs
- import log
- import chessview
- import network
-
- # Mark all windows with our icon
- gtk.window_set_default_icon_name(ICON_NAME)
-
- def loadGladeFile(name, root = None):
- return gtk.glade.XML(os.path.join(GLADE_DIR, name), root, domain = DOMAIN)
-
- class GLibTimer(glchess.ui.Timer):
- """
- """
-
- # FIXME: time.time() is _not_ monotonic so this is not really safe at all...
-
- def __init__(self, ui, feedback, duration):
- self.ui = ui
- self.feedback = feedback
- self.tickTime = 0
- self.reportedTickTime = 0
-
- self.timer = None
- self.tickTimer = None
- self.startTime = None
- self.set(duration * 1000)
-
- def set(self, duration):
- """
- """
- if self.timer is not None:
- gobject.source_remove(self.timer)
- if self.tickTimer is not None:
- gobject.source_remove(self.tickTimer)
- self.duration = duration
- self.consumed = 0
-
- # Notified if the second has changed
-
- def __consumed(self, now):
- # Total time - time at last start - time since start
- if self.startTime is None:
- return self.consumed
- else:
- return self.consumed + (now - self.startTime)
-
- def getRemaining(self):
- """Extends ui.Timer"""
- return self.duration - self.__consumed(int(1000 * time.time()))
-
- def pause(self):
- """Extends ui.Timer"""
- if self.timer is None:
- return
-
- # Calculate the amount of time to use when restarted
- self.consumed = self.__consumed(int(1000 * time.time()))
-
- # Remove timers
- gobject.source_remove(self.timer)
- if self.tickTimer is not None:
- gobject.source_remove(self.tickTimer)
- self.timer = None
- self.tickTimer = None
-
- def run(self):
- """Extends ui.Timer"""
- if self.timer is not None:
- return
-
- # Notify when all time runs out
- self.startTime = int(1000 * time.time())
- self.timer = gobject.timeout_add(self.duration - self.consumed, self.__expired)
-
- # Notify on the next second boundary
- self.__setSecondTimer(self.startTime)
-
- def __setSecondTimer(self, now):
- """Set a timer to expire on the next second boundary"""
- assert(self.tickTimer is None)
-
- # Round the remaining time up to the nearest second
- consumed = self.__consumed(now)
- t = 1000 * (consumed / 1000 + 1)
- if t <= self.reportedTickTime:
- self.tickTime = self.reportedTickTime + 1000
- else:
- self.tickTime = t
-
- # Notify on this time
- if self.tickTime > self.duration:
- self.tickTimer = None
- else:
- self.tickTimer = gobject.timeout_add(self.tickTime - consumed, self.__tick)
-
- def __expired(self):
- """Called by GLib main loop"""
- self.feedback.onTick(0)
- self.feedback.onExpired()
- if self.tickTimer is not None:
- gobject.source_remove(self.tickTimer)
- self.timer = None
- self.tickTimer = None
- return False
-
- def __tick(self):
- """Called by GLib main loop"""
- self.reportedTickTime = self.tickTime
- self.feedback.onTick((self.duration - self.tickTime) / 1000)
- self.tickTimer = None
- self.__setSecondTimer(int(1000 * time.time()))
- return False
-
- def delete(self):
- """Extends ui.Timer"""
- gobject.source_remove(self.timer)
-
- class GtkUI(glchess.ui.UI):
- """
- """
- # The Gtk+ GUI
- _gui = None
-
- # The time stored for animation
- __lastTime = None
- __animationTimer = None
-
- # The Gtk+ list model of the available player types
- __playerModel = None
-
- # The about dialog open
- __aboutDialog = None
-
- # Dictionary of save game dialogs keyed by view
- __saveGameDialogs = None
-
- __renderGL = False
- openGLInfoPrinted = False
-
- # TODO
- __joinGameDialogs = None
- __networkGames = None
-
- __defaultWhiteAI = None
- __defaultBlackAI = None
-
- __attentionCounter = 0
-
- whiteTimeString = '‚àû'
- blackTimeString = '‚àû'
-
- # The window width and height when unmaximised and not fullscreen
- width = None
- height = None
- isFullscreen = False
- isMaximised = False
-
- view = None
-
- def __init__(self, feedback):
- """Constructor for a GTK+ glChess GUI"""
- self.feedback = feedback
- self._watches = {}
- self.__networkGames = {}
- self.newGameDialog = None
- self.loadGameDialog = None
- self.__saveGameDialogs = {}
- self.__joinGameDialogs = []
-
- # Set the message panel to the tooltip style
- # (copied from Gedit)
- # In Gtk+ 2.11+ (I think) tip_window is now private so skip if it's not there (bug #459740)
- tooltip = gtk.Tooltips()
- tooltip.force_window()
- if hasattr(tooltip, 'tip_window') and tooltip.tip_window != None:
- tooltip.tip_window.ensure_style()
- self._tooltipStyle = tooltip.tip_window.get_style()
- else:
- self._tooltipStyle = None
- self._tooltipWidgetsDrawn = {}
-
- self._gui = loadGladeFile('glchess.glade')
- self._gui.signal_autoconnect(self)
-
- self.mainWindow = self._gui.get_widget('glchess_app')
-
- # Workaround as Glade 2 always overrides the system style for toolbars
- self.__getWidget('toolbar').unset_style()
-
- # Create the model for the player types
- self.__playerModel = gtk.ListStore(str, str, str)
- iter = self.__playerModel.append()
- # Translators: Player Type Combo: Player is human controlled
- self.__playerModel.set(iter, 0, '', 1, 'stock_person', 2, _('Human'))
-
- self.__logWindow = log.LogWindow(self._gui.get_widget('log_notebook'))
-
- # Make preferences dialog
- self.preferences = dialogs.GtkPreferencesDialog(self)
-
- # Balance space on each side of the history combo
- group = gtk.SizeGroup(gtk.SIZE_GROUP_BOTH)
- group.add_widget(self.__getWidget('left_nav_box'))
- group.add_widget(self.__getWidget('right_nav_box'))
-
- # History combo displays text data
- combo = self.__getWidget('history_combo')
- cell = gtk.CellRendererText()
- combo.pack_start(cell, False)
- combo.add_attribute(cell, 'text', 2)
-
- # Add launchpad integration
- widget = self._gui.get_widget('help2_menu')
- LaunchpadIntegration.set_sourcepackagename('gnome-games')
- LaunchpadIntegration.add_items(widget,1,True,False)
-
- self._updateViewButtons()
-
- # Watch for config changes
- for key in ['show_toolbar', 'show_history', 'fullscreen',
- 'show_3d', 'show_3d_smooth', 'show_comments', 'show_numbering',
- 'show_move_hints',
- 'width', 'height',
- 'move_format', 'promotion_type', 'board_view',
- 'enable_networking']:
- glchess.config.watch(key, self.__applyConfig)
-
- # Public methods
-
- def setTooltipStyle(self, widget):
- """Set a widget to be in the tooltip style.
-
- 'widget' is the widget to modify.
- """
- if self._tooltipStyle is None:
- return
- widget.set_style(self._tooltipStyle)
- widget.connect("expose_event", self._on_tooltip_expose_event)
- widget.queue_draw()
-
- def _on_tooltip_expose_event(self, widget, event):
- """Gtk+ callback"""
- allocation = widget.allocation
- widget.style.paint_flat_box(widget.window, gtk.STATE_NORMAL, gtk.SHADOW_OUT, None, widget, "tooltip",
- allocation.x, allocation.y, allocation.width, allocation.height)
-
- # The first draw is corrupt for me so draw it twice.
- # Bonus points to anyone who tracks down the problem and fixes it
- if not self._tooltipWidgetsDrawn.has_key(widget):
- self._tooltipWidgetsDrawn[widget] = True
- widget.queue_draw()
-
- def watchFileDescriptor(self, fd):
- """Extends ui.UI"""
- self._watches[fd] = gobject.io_add_watch(fd, gobject.IO_IN | gobject.IO_PRI | gobject.IO_HUP | gobject.IO_ERR, self.__readData)
-
- def unwatchFileDescriptor(self, fd):
- """Extends ui.UI"""
- gobject.source_remove(self._watches.pop(fd))
-
- def writeFileDescriptor(self, fd):
- """Extends ui.UI"""
- gobject.io_add_watch(fd, gobject.IO_OUT, self.__writeData)
-
- def addTimer(self, feedback, duration):
- """Extends ui.UI"""
- return GLibTimer(self, feedback, duration)
-
- def __timerExpired(self, method):
- method()
- return True
-
- def __readData(self, fd, condition):
- #print (fd, condition)
- return self.feedback.onReadFileDescriptor(fd)
-
- def __writeData(self, fd, condition):
- #print (fd, condition)
- return self.feedback.onWriteFileDescriptor(fd)
-
- def addAIEngine(self, name):
- """Register an AI engine.
-
- 'name' is the name of the engine.
- TODO: difficulty etc etc
- """
- iter = self.__playerModel.append()
- self.__playerModel.set(iter, 0, name, 1, 'stock_notebook', 2, name)
-
- # Get the human to play against this AI
- if self.__defaultBlackAI is None:
- self.__defaultBlackAI = name
-
- def setView(self, title, feedback, isPlayable = True):
- """Extends ui.UI"""
- moveFormat = glchess.config.get('move_format')
- showComments = glchess.config.get('show_comments')
- self.view = chessview.GtkView(self, feedback, moveFormat = moveFormat, showComments = showComments)
- self.view.setTitle(title)
- self.view.isPlayable = isPlayable
- self.view.viewWidget.setRenderGL(self.__renderGL)
- viewport = self.__getWidget('game_viewport')
- child = viewport.get_child()
- if child is not None:
- viewport.remove(child)
- viewport.add(self.view.widget)
-
- # Set toolbar/menu buttons to state for this game
- self._updateViewButtons()
-
- # Update timers
- if self.view is not None:
- self.setTimers(self.view.whiteTime, self.view.blackTime)
-
- return self.view
-
- def updateTitle(self):
- """
- """
- # Set the window title to the name of the game
- if self.view is not None and len(self.view.title) > 0:
- if self.view.needsSaving:
- # Translators: Window title when playing a game that needs saving
- title = _('Chess - *%(game_name)s') % {'game_name': self.view.title}
- else:
- # Translators: Window title when playing a game that is saved
- title = _('Chess - %(game_name)s') % {'game_name': self.view.title}
- else:
- # Translators: Window title when not playing a game
- title = _('Chess')
- self.mainWindow.set_title(title)
-
- def addLogWindow(self, title, executable, description):
- """
- """
- return self.__logWindow.addView(title, executable, description)
-
- def setTimers(self, whiteTime, blackTime):
- """
- """
- # Translators: Game Timer Label: Indicates that game has no time limit
- unlimitedTimeText = _('‚àû')
-
- if whiteTime is None:
- whiteString = unlimitedTimeText
- else:
- t = whiteTime[1]
- whiteString = '%i:%02i' % (t / 60, t % 60)
- if blackTime is None:
- blackString = unlimitedTimeText
- else:
- t = blackTime[1]
- blackString = '%i:%02i' % (t / 60, t % 60)
-
- if whiteString != self.whiteTimeString:
- self.whiteTimeString = whiteString
- self._gui.get_widget('white_time_label').queue_draw()
- if blackString != self.blackTimeString:
- self.blackTimeString = blackString
- self._gui.get_widget('black_time_label').queue_draw()
-
- def run(self):
- """Run the UI.
-
- This method will not return.
- """
- # Load configuration
- for name in ['show_toolbar', 'show_history', 'show_3d', 'show_3d_smooth',
- 'show_comments', 'show_numbering', 'show_move_hints',
- 'move_format', 'promotion_type', 'board_view', 'maximised',
- 'enable_networking']:
- try:
- value = glchess.config.get(name)
- except glchess.config.Error:
- pass
- else:
- self.__applyConfig(name, value)
- self.__resize()
-
- self.mainWindow.show()
-
- # Apply the fullscreen flag after the window has been shown otherwise
- # gtk.Window.unfullscreen() stops working if the window is set to fullscreen
- # before being shown. I haven't been able to reproduce this in the simple
- # case (GTK+ 2.10.6-0ubuntu3).
- self.__applyConfig('fullscreen', glchess.config.get('fullscreen'))
-
- gtk.main()
-
- # Extended methods
-
- def reportGameLoaded(self, game):
- """Extends glchess.ui.UI"""
- dialogs.GtkNewGameDialog(self, self.__playerModel, game)
-
- def addNetworkDialog(self, feedback):
- """Extends glchess.ui.UI"""
- self.__networkDialog = network.GtkNetworkGameDialog(self, feedback)
- return self.__networkDialog
-
- def addNetworkGame(self, name, game):
- """Extends glchess.ui.UI"""
- self.__networkDialog.addNetworkGame(name, game)
-
- def removeNetworkGame(self, game):
- """Extends glchess.ui.UI"""
- self.__networkDialog.removeNetworkGame(game)
-
- def requestSave(self, title):
- """Extends glchess.ui.UI"""
- dialog = gtk.MessageDialog(flags = gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- type = gtk.MESSAGE_WARNING,
- message_format = title)
- # Translators: Save Game Dialog: Notice that game needs saving
- dialog.format_secondary_text(_("If you don't save the changes to this game will be permanently lost"))
- # Translators: Save Game Dialog: Discard game button
- dialog.add_button(_('Close _without saving'), gtk.RESPONSE_OK)
- dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT)
- dialog.add_button(gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT)
-
- response = dialog.run()
- dialog.destroy()
- if response == gtk.RESPONSE_ACCEPT:
- return glchess.ui.SAVE_YES
- elif response == gtk.RESPONSE_OK:
- return glchess.ui.SAVE_NO
- else:
- return glchess.ui.SAVE_ABORT
-
- def close(self):
- """Extends glchess.ui.UI"""
- # Save the window size
- if self.width is not None:
- glchess.config.set('width', self.width)
- if self.height is not None:
- glchess.config.set('height', self.height)
-
- # Protected methods
-
- def _incAttentionCounter(self, offset):
- """
- """
- self.__attentionCounter += offset
- self.__updateAttention()
-
- def __updateAttention(self):
- """
- """
- widget = self.mainWindow
- widget.set_urgency_hint(self.__attentionCounter != 0 and not widget.is_active())
-
- def _on_focus_changed(self, widget, event):
- """Gtk+ callback"""
- self.__updateAttention()
-
- def _saveView(self, view, path):
- """
- """
- if path is None:
- error = None
- else:
- error = view.feedback.save(path)
-
- if error is not None:
- return error
- self.__saveGameDialogs.pop(view)
-
- # Private methods
-
- def __resize(self):
- try:
- width = glchess.config.get('width')
- height = glchess.config.get('height')
- except glchess.config.Error:
- return
-
- self.mainWindow.resize(width, height)
-
- def __applyConfig(self, name, value):
- """
- """
- if name == 'width' or name == 'height':
- self.__resize()
- return
-
- # Show/hide the toolbar
- if name == 'show_toolbar':
- toolbar = self.__getWidget('toolbar')
- if value is True:
- toolbar.show()
- else:
- toolbar.hide()
-
- elif name == 'enable_networking':
- menuItem = self.__getWidget('menu_play_online_item')
- toolbarButton = self.__getWidget('play_online_button')
- if value is True:
- menuItem.show()
- toolbarButton.show()
- else:
- menuItem.hide()
- toolbarButton.hide()
-
- # Show/hide the history
- elif name == 'show_history':
- box = self.__getWidget('navigation_box')
- if value is True:
- box.show()
- else:
- box.hide()
-
- # Maximised mode
- elif name == 'maximised':
- window = self.mainWindow
- if value is True:
- window.maximize()
- else:
- window.unmaximize()
-
- # Fullscreen mode
- elif name == 'fullscreen':
- window = self.mainWindow
- if value is True:
- window.fullscreen()
- else:
- window.unfullscreen()
-
- # Enable/disable OpenGL rendering
- elif name == 'show_3d':
- if value and not chessview.haveGLSupport:
- # Translators: No 3D Dialog: Title
- title = _('Unable to enable 3D mode')
- errors = '\n'.join(chessview.openGLErrors)
- # Translators: No 3D Dialog: Notification to user that they do not have libraries required to enable 3D.
- # %(error)s will be replaced with a list of reasons why 3D is not available.
- description = _("""You are unable to play in 3D mode due to the following problems:
- %(errors)s
-
- Please contact your system administrator to resolve these problems, until then you will be able to play chess in 2D mode.""") % {'errors': errors}
- dialog = gtk.MessageDialog(type = gtk.MESSAGE_WARNING, message_format = title)
- dialog.format_secondary_text(description)
- dialog.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
- dialog.run()
- dialog.destroy()
- glchess.config.set('show_3d', False)
- value = False
- self.__renderGL = value
- self.__getWidget('menu_view_3d').set_active(value)
- self.view.viewWidget.setRenderGL(value)
-
- elif name == 'show_3d_smooth':
- if not chessview.haveGLAccumSupport:
- value = False
- self.view.feedback.showSmooth(value)
-
- elif name == 'show_comments':
- self.view.setShowComments(value)
-
- elif name == 'show_move_hints':
- self.view.feedback.showMoveHints(value)
-
- elif name == 'show_numbering':
- self.view.feedback.showBoardNumbering(value)
-
- elif name == 'move_format':
- self.view.setMoveFormat(value)
-
- elif name == 'promotion_type':
- pass
-
- elif name == 'board_view':
- pass
-
- else:
- assert(False), 'Unknown config item: %s' % name
-
- def startAnimation(self):
- """Start the animation callback"""
- if self.__animationTimer is None:
- self.__lastTime = time.time()
- self.__animationTimer = gobject.timeout_add(10, self.__animate)
-
- def __animate(self):
- # Get the timestep, if it is less than zero or more than a second
- # then the system clock was probably changed.
- now = time.time()
- step = now - self.__lastTime
- if step < 0.0:
- step = 0.0
- elif step > 1.0:
- step = 1.0
- self.__lastTime = now
-
- # Animate!
- animating = self.feedback.onAnimate(step)
- if not animating:
- self.__animationTimer = None
-
- # Keep/delete timer
- return animating
-
- def __getWidget(self, name):
- widget = self._gui.get_widget(name)
- assert(widget is not None), 'Unable to find widget: %s' % name
- return widget
-
- def _on_white_time_paint(self, widget, event):
- """Gtk+ callback"""
- self.__drawTime(self.whiteTimeString, widget, (0.0, 0.0, 0.0), (1.0, 1.0, 1.0))
-
- def _on_black_time_paint(self, widget, event):
- """Gtk+ callback"""
- self.__drawTime(self.blackTimeString, widget, (1.0, 1.0, 1.0), (0.0, 0.0, 0.0))
-
- def __drawTime(self, text, widget, fg, bg):
- """
- """
- if widget.state == gtk.STATE_INSENSITIVE:
- alpha = 0.5
- else:
- alpha = 1.0
- context = widget.window.cairo_create()
- context.set_source_rgba(bg[0], bg[1], bg[2], alpha)
- context.paint()
-
- (_, _, w, h) = widget.get_allocation()
-
- context.set_source_rgba(fg[0], fg[1], fg[2], alpha)
- context.select_font_face('fixed', cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
- context.set_font_size(0.6 * h)
- (x_bearing, y_bearing, width, height, _, _) = context.text_extents(text)
- context.move_to((w - width) / 2 - x_bearing, (h - height) / 2 - y_bearing)
- context.show_text(text)
-
- # Resize to fit text
- widget.set_size_request(int(width) + 6, -1)
-
- def _on_toggle_3d_clicked(self, widget):
- """Gtk+ callback"""
- if widget.get_active():
- value = True
- else:
- value = False
- glchess.config.set('show_3d', value)
-
- def _on_show_logs_clicked(self, widget):
- """Gtk+ callback"""
- window = self._gui.get_widget('log_window')
- if widget.get_active():
- window.present()
- else:
- window.hide()
-
- def _on_history_combo_changed(self, widget):
- """Gtk+ callback"""
- model = widget.get_model()
- iter = widget.get_active_iter()
- if iter is None:
- return
-
- # Get the move number
- moveNumber = model.get_value(iter, 1)
-
- if moveNumber == len(model) - 1:
- moveNumber = -1
-
- # Disable buttons when at the end
- haveMoves = len(model) > 1
- for widget in ('first_move_button', 'prev_move_button'):
- self.__getWidget(widget).set_sensitive(haveMoves and moveNumber != 0)
- for widget in ('last_move_button', 'next_move_button'):
- self.__getWidget(widget).set_sensitive(haveMoves and moveNumber != -1)
-
- self.view._setMoveNumber(moveNumber)
-
- def __selectMoveNumber(self, moveNumber):
- """FIXME
- """
- combo = self.__getWidget('history_combo')
-
- # Limit moves to the maximum value
- maxNumber = len(combo.get_model())
-
- # Allow negative indexing
- if moveNumber < 0:
- moveNumber = maxNumber + moveNumber
- if moveNumber < 0:
- moveNumber = 0
- if moveNumber >= maxNumber:
- moveNumber = maxNumber - 1
-
- combo.set_active(moveNumber)
-
- def __selectMoveNumberRelative(self, offset):
- """FIXME
- """
- combo = self.__getWidget('history_combo')
- selected = combo.get_active()
- maxNumber = len(combo.get_model())
- new = selected + offset
- if new < 0:
- new = 0
- elif new >= maxNumber:
- new = maxNumber - 1
- self.__selectMoveNumber(new)
-
- def _on_history_start_clicked(self, widget):
- """Gtk+ callback"""
- self.__selectMoveNumber(0)
-
- def _on_history_previous_clicked(self, widget):
- """Gtk+ callback"""
- self.__selectMoveNumberRelative(-1)
-
- def _on_history_next_clicked(self, widget):
- """Gtk+ callback"""
- self.__selectMoveNumberRelative(1)
-
- def _on_history_latest_clicked(self, widget):
- """Gtk+ callback"""
- self.__selectMoveNumber(-1)
-
- def _updateViewButtons(self):
- """
- """
- enable = self.view is not None and self.view.isPlayable
- for widget in ('save_game_button', 'menu_save_item', 'menu_save_as_item'):
- self.__getWidget(widget).set_sensitive(enable)
-
- combo = self.__getWidget('history_combo')
- if self.view is None:
- if combo.get_model() != None:
- combo.set_model(None)
- else:
- (model, selected) = self.view._getModel()
- combo.set_model(model)
- if selected < 0:
- selected = len(model) + selected
- combo.set_active(selected)
- self.__getWidget('navigation_box').set_sensitive(enable)
-
- enable = enable and self.view.gameResult is None
- '''FIXME! for widget in ('menu_resign', 'resign_button', 'menu_claim_draw'):
- self.__getWidget(widget).set_sensitive(enable)'''
-
- def _on_new_game_button_clicked(self, widget):
- """Gtk+ callback"""
- if self.newGameDialog:
- self.newGameDialog.window.present()
- else:
- self.newGameDialog = dialogs.GtkNewGameDialog(self, self.__playerModel)
-
- def _on_join_game_button_clicked(self, widget):
- """Gtk+ callback"""
- self.feedback.onNewNetworkGame()
-
- def _on_open_game_button_clicked(self, widget):
- """Gtk+ callback"""
- if self.loadGameDialog:
- self.loadGameDialog.window.present()
- else:
- self.loadGameDialog = dialogs.GtkLoadGameDialog(self)
-
- def _on_save_game_button_clicked(self, widget):
- """Gtk+ callback"""
- if self.view.feedback.getFileName() is not None:
- self.view.feedback.save()
- return
-
- try:
- dialog = self.__saveGameDialogs[self.view]
- except KeyError:
- dialog = self.__saveGameDialogs[self.view] = dialogs.GtkSaveGameDialog(self, self.view)
- dialog.window.present()
-
- def _on_save_as_game_button_clicked(self, widget):
- """Gtk+ callback"""
- try:
- dialog = self.__saveGameDialogs[self.view]
- except KeyError:
- dialog = self.__saveGameDialogs[self.view] = dialogs.GtkSaveGameDialog(self, self.view, self.view.feedback.getFileName())
- dialog.window.present()
-
- def _on_undo_move_clicked(self, widget):
- """Gtk+ callback"""
- self.view.feedback.undo()
-
- def _on_resign_clicked(self, widget):
- """Gtk+ callback"""
- self.view.feedback.resign()
-
- def _on_claim_draw_clicked(self, widget):
- """Gtk+ callback"""
- if self.view.feedback.claimDraw():
- return
-
- # Translators: Draw Dialog: Title
- title = _("Unable to claim draw")
- # Translators: Draw Dialog: Notify user why they cannot claim draw
- message = _("""You may claim a draw when:
- a) The board has been in the same state three times (Three fold repetition)
- b) Fifty moves have occured where no pawn has moved and no piece has been captured (50 move rule)""")
-
- dialog = gtk.MessageDialog(flags = gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- type = gtk.MESSAGE_WARNING,
- message_format = title)
- dialog.format_secondary_text(message)
- dialog.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_ACCEPT)
- dialog.run()
- dialog.destroy()
-
- def _on_preferences_clicked(self, widget):
- """Gtk+ callback"""
- self.preferences.setVisible(True)
-
- def _on_help_clicked(self, widget):
- """Gtk+ callback"""
- try:
- gtk.show_uri(self.mainWindow.get_screen(), "ghelp:glchess", gtk.get_current_event_time())
- except gobject.GError, e:
- # TODO: This should be a pop-up dialog
- print _('Unable to display help: %s') % str(e)
-
- def _on_view_fullscreen_clicked(self, widget):
- """Gtk+ callback"""
- glchess.config.set('fullscreen', True)
-
- def _on_view_unfullscreen_clicked(self, widget):
- """Gtk+ callback"""
- glchess.config.set('fullscreen', False)
-
- def _on_3d_support_dialog_delete_event(self, widget, event):
- """Gtk+ callback"""
- # Stop the dialog from deleting itself
- return True
-
- def _on_3d_support_dialog_response(self, widget, responseId):
- """Gtk+ callback"""
- if self.__aboutDialog is not None:
- return
- widget.hide()
- return False
-
- def _on_about_clicked(self, widget):
- """Gtk+ callback"""
- if self.__aboutDialog is not None:
- return
-
- dialog = self.__aboutDialog = gtk.AboutDialog()
- dialog.set_transient_for(self.mainWindow)
- dialog.set_name(APPNAME)
- dialog.set_version(VERSION)
- dialog.set_copyright(COPYRIGHT)
- dialog.set_license(LICENSE[0] + '\n\n' + LICENSE[1] + '\n\n' +LICENSE[2])
- dialog.set_wrap_license(True)
- dialog.set_comments(DESCRIPTION)
- dialog.set_authors(AUTHORS)
- dialog.set_artists(ARTISTS)
- dialog.set_translator_credits(_("translator-credits"))
- dialog.set_website(WEBSITE)
- dialog.set_website_label(WEBSITE_LABEL)
- dialog.set_logo_icon_name(ICON_NAME)
- dialog.connect('response', self._on_glchess_about_dialog_close)
- dialog.show()
-
- def _on_glchess_about_dialog_close(self, widget, event):
- """Gtk+ callback"""
- self.__aboutDialog.destroy()
- self.__aboutDialog = None
- return False
-
- def _on_log_window_delete_event(self, widget, event):
- """Gtk+ callback"""
- self._gui.get_widget('menu_view_logs').set_active(False)
-
- # Stop the event - the window will be closed by the menu event
- return True
-
- def _on_resize(self, widget, event):
- """Gtk+ callback"""
- if self.isMaximised or self.isFullscreen:
- return
- self.width = event.width
- self.height = event.height
-
- def _on_window_state_changed(self, widget, event):
- """Gtk+ callback"""
- if event.changed_mask & gtk.gdk.WINDOW_STATE_MAXIMIZED:
- self.isMaximised = event.new_window_state & gtk.gdk.WINDOW_STATE_MAXIMIZED != 0
- glchess.config.set('maximised', self.isMaximised)
-
- if event.changed_mask & gtk.gdk.WINDOW_STATE_FULLSCREEN:
- self.isFullscreen = event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN != 0
- if self.isFullscreen:
- self._gui.get_widget('menu_fullscreen').hide()
- self._gui.get_widget('menu_leave_fullscreen').show()
- else:
- self._gui.get_widget('menu_leave_fullscreen').hide()
- self._gui.get_widget('menu_fullscreen').show()
-
- def _on_close_window(self, widget, event):
- """Gtk+ callback"""
- self.feedback.onQuit()
- return True
-
- def _on_menu_quit(self, widget):
- """Gtk+ callback"""
- self.feedback.onQuit()
-
- if __name__ == '__main__':
- ui = GtkUI()
- ui.run()
-